/*
 * IUnit.cpp
 *
 *  Created on: 07.12.2011
 *      Author: Kirill Blinov
 *      Copyright: LGPL
 */

#include "IUnit.h"

IUnit::IUnit( GAME_OBJECT* VisualisationInfo ) :
	physicParams(NULL), sequenceStarted(false)
{
	visualisationInfo = VisualisationInfo;

	//Move model position to coordinate center
	visualisationInfo->firstCorner  -= VisualisationInfo->sphereCenter;
	visualisationInfo->secondCorner -= VisualisationInfo->sphereCenter;
	visualisationInfo->correctionMatrix = glm::translate( glm::mat4(1.0), (visualisationInfo->sphereCenter) );
	visualisationInfo->sphereCenter = glm::vec3( 0, 0, 0 );
	glm::mat4 TranslationMatrix = glm::translate( glm::mat4(1.0), visualisationInfo->translation );
	glm::mat4 Rotation = glm::toMat4( VisualisationInfo->orientation );

	visualisationInfo->worldMatrix =  Rotation * TranslationMatrix;
}

IUnit::IUnit( const IUnit& Base ) : physicParams(NULL)
{
	visualisationInfo = new GAME_OBJECT( *Base.visualisationInfo );
}

IUnit::~IUnit()
{
	if ( physicParams != NULL )
	{
		delete physicParams;
	}

	delete visualisationInfo; //It should be always allocated
}

/*
 * Returns true on the first call only, so the name can be changed only set once.
 */
bool
IUnit::SetName( const std::string Name )
{
	bool Result = !name.empty();

	if ( Result )
	{
		name = Name;
	}

	return Result;
}

/*
 * Sets initial object parameters like a speed, velocity e.t.c.
 * Returns true on the first call only.
 */
bool
IUnit::SetPhysicParams( const UNIT_PHYSIC_PARAMS &PhysicParams )
{
	bool Result = ( NULL == physicParams );
	if ( Result )
	{
		physicParams = new UNIT_PHYSIC_PARAMS( PhysicParams );
		glm::mat4 Translation = glm::translate( glm::mat4(1.0f), physicParams->initialPosition );
		glm::mat4 Rotation = glm::toMat4( physicParams->initialOrientation );

		visualisationInfo->translation += physicParams->initialPosition;
		visualisationInfo->orientation = visualisationInfo->orientation + physicParams->initialOrientation;
		visualisationInfo->worldMatrix *=  Rotation * Translation;
	}

	return Result;
}

const std::string
IUnit::GetName() const
{
	return name;
}

UINT_EVENT
IUnit::PopEvent()
{
	UINT_EVENT Event = eventQueue.front();
	eventQueue.pop();
	return Event;
}

void
IUnit::Translate( const glm::vec3 Translation )
{
	glm::mat4 TranslationMatrix = glm::translate( glm::mat4(1.0), Translation );
	visualisationInfo->translation += Translation;
	visualisationInfo->worldMatrix *= TranslationMatrix;
}

/*
 * The function sets a flag to show do we have to recreate
 * textures array just after UpdateTexture() call
 */
void
IUnit::StartUpdatingSequence()
{
	sequenceStarted = true;
}

void
IUnit::FinishUpdatingSequence()
{
	if ( sequenceStarted )
	{
		sequenceStarted = false;
		//TODO Add loading of all diffuse textures and recreating textures array
	}
}

/*
 * The function changes one texture of diffuse textures array and
 * in concordance with the sequenceStarted flag recreates or not texture array
 */
bool
IUnit::UpdateTexture( const TEXTURE_DESCRIPTOR &Texture, const UINT Subobject )
{
	bool Result = false;

	for ( std::vector<TEXTURE_DESCRIPTOR>::iterator Intit = textures.begin(), Intend = textures.end();
		  Intit != Intend; ++Intit )
	{
		TEXTURE_DESCRIPTOR *TextureDesc = Intit.base();

		if ( TextureDesc->alias == Texture.alias )
		{
			TextureDesc->name = Texture.name;
			TextureDesc->textureGLid = Texture.textureGLid;
			Result = true;

			if ( !sequenceStarted )
			{
				//TODO Add loading of all diffuse textures and recreating textures array
			}

			break;
		}
	}

	return Result;
}
